// data_structures.cpp
// Customizer
// Protea Customizer / Business Logic for managing data structures (buffers)
// Copyright (C) 2003, 2004, 2005 eXegeSys, Inc.
// Copyright (C) 2008 Bruce A. James
//
// This program is part of the Protea Project.
//
// The Protea Project is free software; you can redistribute it and/or modify it 
// under the terms of the GNU General Public License as published by the 
// Free Software Foundation, either version 3 of the License, or (at your 
// option) any later version.
//
// The Protea Project is distributed in the hope that it will be useful, but 
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 
// for more details.
// 
// You should have received a copy of the GNU General Public License along 
// with this program.  If not, see <http://www.gnu.org/licenses/>.
//
// Please send correspondence to:
//
// theproteaproject@gmail.com
//

#include "customizer.h"


//
//@ CHA AddDataStructure
//@ COD AddDataStructure
//@ NUM 190
//@ CRI FORMAT_NAME (or number)
//@ TAB FORMAT_DESCRIPTR Read
//@ TAB FIELD_DESCRIPTOR Read 
//@ TAB DATA_STRUCTURES Write
//
//@ GEN AddDataStructure will add a record to relate a field to a particular format
//
TRANSACTION_CODE( AddDataStructure ) {
	//@ BLD Start of Transaction
	//@ GRS
	START_TXN( AddDataStructure );
		//@ BLD Start of Database transaction
		START_DB_TXN();
			AddDataStructureInternal( &txnvars, false );
		//@ BLD End of Database transaction
		END_DB_TXN();

		LOG_TRANSACTION();

		// Send the result back
		App->TransResponse( txnvars.result, txnvars.buffer, TRANS_HEADER_TYPE );

	CLEANUP_TXN();
	END_TXN();
	//@ GRE
	//@ BLD End of Transaction
};







//
//@ CHA DelDataStructure
//@ COD DelDataStructure
//@ NUM 190
//@ CRI FORMAT_NAME (or number)
//@ TAB FORMAT_DESCRIPTR Read
//@ TAB FIELD_DESCRIPTOR Read 
//@ TAB DATA_STRUCTURES Write
//
//@ GEN DelDataStructure will delete a record relating a field to a particular format
//
TRANSACTION_CODE( DelDataStructure ) {
	START_TXN( DelDataStructure );
		START_DB_TXN();
			DelDataStructureInternal( &txnvars, false );
		END_DB_TXN();

		LOG_TRANSACTION();
	CLEANUP_TXN()
	END_TXN();
};




//@ CHA FieldWhereUsed
//@ COD FieldWhereUsed
//@ NUM 190
//@ CRI FIELD_NAME
//@ CRI APPL_NBR
//@ TAB FIELD_DESCRIPTOR Read
//@ TAB DATA_STRUCTURES Read
//@ TAB FORMAT_DESCRIPTR Read
//
//@ GEN FieldWhereUsed will return format records that contain a particular field
//
/*  --- Replacing Old Code --- 
TRANSACTION_CODE( FieldWhereUsed ) 
{

	XCBuffer* TransBuf = NULL;
	XCBuffer* detail = NULL;
	XCDBStatement* stmt = NULL;

	//@ GRS Start the transaction
	START_TXN( FieldWhereUsed );

		TransBuf = App->CreateBuffer( FMT_DATA_STRUCTURES, false );

		//@ Move supplied buffer information into transaction buffer
		TransBuf->MoveCorresponding( txnvars.buffer, txnvars.Errors );

		//@ Check for validation errors
		txnvars.Errors->Check();

		START_DB_TXN();
			//@ UTL LookupNumberFromName to translate field name into a number
			if (!LookupNumberFromName( &txnvars, txnvars.buffer, TransBuf, FLD_FIELD_NUMBER, FLD_FIELD_NAME, FMT_FIELD_DESCRIPTOR ))
				txnvars.Errors->Add( ERR_DOESNT_EXIST, SEV_ERROR, FLD_FIELD_NAME, 1, ERR_FIELD ); 

			txnvars.Errors->Check();

			TransBuf->DebugDump();

			//@ Send the header information
			txnvars.buffer->MoveCorresponding( TransBuf, txnvars.Errors );
			App->TransResponse( txnvars.result, txnvars.buffer, TRANS_HEADER_TYPE );

			//@ Check if DATA_STRUCTURES record exists
			stmt = GetFieldWhereUsed( TransBuf, &txnvars );
			if (!stmt->Eof()) {
				//@ Send all detail information packets
				int child = txnvars.buffer->GetChildFormat();
				if (child) {
					detail = App->CreateBuffer( child, false );

					// Send all other data packets
					while (!stmt->Eof()) {
						detail->MoveCorresponding( TransBuf, txnvars.Errors );
						LookupNameFromNumber( &txnvars, TransBuf, detail, FLD_FORMAT_NUMBER, FLD_FORMAT_NAME, FMT_FORMAT_DESCRIPTR );
						txnvars.Errors->Check();

						App->TransResponse( txnvars.result, detail, TRANS_DETAIL_TYPE );
						stmt->MoveNext();
					};
				};
			};

		END_DB_TXN();

	CLEANUP_TXN()
		App->CleanupObjects( 3, &TransBuf, &detail, &stmt );
	END_TXN();
	//@ GRE End the transaction
};
*/

TRANSACTION_CODE( FieldWhereUsed ) 
{

	XCBuffer* Data_Structures = NULL;
	XCBuffer* Format_Descriptr = NULL;
	XCBuffer* Component_Defn = NULL;
	XCBuffer* detail = NULL;
	XCDBStatement* stmt = NULL;

	//@ GRS Start the transaction
	START_TXN( FieldWhereUsed );

		Data_Structures = App->CreateBuffer( FMT_DATA_STRUCTURES, false );
		Format_Descriptr = App->CreateBuffer( FMT_FORMAT_DESCRIPTR, false );
		Component_Defn = App->CreateBuffer( FMT_COMPONENT_DEFN, false );

		//@ Move supplied buffer information into transaction buffer
		Data_Structures->MoveCorresponding( txnvars.buffer, txnvars.Errors );

		//@ Check for validation errors
		txnvars.Errors->Check();

		START_DB_TXN();
			//@ UTL LookupNumberFromName to translate field name into a number
			if (!LookupNumberFromName( &txnvars, txnvars.buffer, Data_Structures, FLD_FIELD_NUMBER, FLD_FIELD_NAME, FMT_FIELD_DESCRIPTOR ))
				txnvars.Errors->Add( ERR_DOESNT_EXIST, SEV_ERROR, FLD_FIELD_NAME, 1, ERR_FIELD ); 
			txnvars.Errors->Check();

			Data_Structures->DebugDump();

			//@ Send the header information
			txnvars.buffer->MoveCorresponding( Data_Structures, txnvars.Errors );
			App->TransResponse( txnvars.result, txnvars.buffer, TRANS_HEADER_TYPE );

			//@ Check if DATA_STRUCTURES record exists
			stmt = GetFieldWhereUsed( Data_Structures, &txnvars );
			if (!stmt->Eof()) 
			{
				//@ Send all detail information packets
				int child = txnvars.buffer->GetChildFormat();
				if (child) {
					detail = App->CreateBuffer( child, false );

					// Send all other data packets
					while (!stmt->Eof()) 
					{
						Format_Descriptr->Clear();
						Format_Descriptr->MoveCorresponding( Data_Structures, txnvars.Errors, false );
						Database_Review( Format_Descriptr, &txnvars, FLD_FORMAT_NUMBER );
						detail->MoveCorresponding( Format_Descriptr, txnvars.Errors, false );
						txnvars.Errors->Check();

						Component_Defn->Clear();
						Component_Defn->MoveCorresponding( Format_Descriptr, txnvars.Errors, false );
						if ( !Component_Defn->GetField( FLD_COMPONENT_ID )->CompareZero() )
						{
							Component_Defn->GetField( FLD_COMPONENT_NAME )->SetString( "Default" );
						}
						else
						{
							Database_Review( Component_Defn, &txnvars, FLD_COMPONENT_ID );
						}
						detail->MoveCorresponding( Component_Defn, txnvars.Errors, false );
						txnvars.Errors->Check();

						detail->MoveCorresponding( Data_Structures, txnvars.Errors, false );
						txnvars.Errors->Check();

						App->TransResponse( txnvars.result, detail, TRANS_DETAIL_TYPE );
						stmt->MoveNext();
					};
				};
			};

		END_DB_TXN();

	CLEANUP_TXN()
		App->CleanupObjects( 5, &Data_Structures, &Format_Descriptr, &Component_Defn, &detail, &stmt );
	END_TXN();
	//@ GRE End the transaction
};


//
//@ CHA ChgDataStructure
//@ COD ChgDataStructure
//@ NUM 190
//@ CRI FIELD_NAME
//@ CRI APPL_NBR
//@ TAB DATA_STRUCTURE Write
//
//@ GEN ChgDataStructure will change DATA_STRUCTURE records
//
TRANSACTION_CODE( ChgDataStructure ) {
	//@ GRS Start the transaction
	START_TXN( ChgDataStructure );
		START_DB_TXN();
			ChgDataStructureInternal( &txnvars, false );
		END_DB_TXN();

		LOG_TRANSACTION();
	CLEANUP_TXN();
	END_TXN();
	//@ GRE End the transaction
};
